package com.gx.telephonedemo2;

import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.net.Uri;
import android.os.RemoteException;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;

import com.android.internal.telephony.ITelephony;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * Description:
 * Author: GX
 * CreateDate: 2019/8/14 19:41
 * UpdateUser: GX
 * UpdateDate: 2019/8/14 19:41
 * UpdateRemark:
 * Version: 1.0
 */
public final class BlockCallHelper {
    private static final String TAG = "BlockCallHelper";

    private Context mContext;

    private TelephonyManager tManger;

    private List<String> phones;

    private BlockCallBack bcb;

    private PhoneCallListener mPhoneCallListener;

    //////////////////////////////////////////
    private static final class Factory {
        private static final BlockCallHelper instance = new BlockCallHelper();
    }

    public static BlockCallHelper getInstance() {
        return Factory.instance;
    }

    /**
     * 初始化上下文以及数据
     * @param context
     */
    public BlockCallHelper init(Context context) {
        if (context == null) {
            throw new NullPointerException("context == null!");
        }

        this.mContext = context;
        this.tManger = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
        if(mPhoneCallListener == null) {
            mPhoneCallListener = new PhoneCallListener();
        }
        tManger.listen(mPhoneCallListener, PhoneCallListener.LISTEN_CALL_STATE);
        return this;
    }

    /**
     * 注入需要拦截的手机号
     * @param blockCalls 需要拦截的号码
     */
    public BlockCallHelper injectBlockPhoneNum(ArrayList<String> blockCalls) {
        this.phones = blockCalls;
        return this;
    }
    /**
     * 结束通话
     */
    private void endCall() {
        Class<TelephonyManager> tmc = TelephonyManager.class;
        Method getITelephonyMethod;
        try {
            getITelephonyMethod = tmc.getDeclaredMethod("getITelephony", (Class[]) null);
            getITelephonyMethod.setAccessible(true);
            ITelephony iTelephony = (ITelephony) getITelephonyMethod.invoke(tManger, (Object[]) null);
            iTelephony.endCall();
        } catch (NoSuchMethodException e1) {
            e1.printStackTrace();
        } catch (InvocationTargetException e2) {
            e2.printStackTrace();
        } catch (IllegalAccessException e3) {
            e3.printStackTrace();
        } catch (RemoteException e4) {
            e4.printStackTrace();
        }
    }

    private final class PhoneCallListener extends PhoneStateListener {
        @Override
        public void onCallStateChanged(int state, String incomingNumber) {
            switch (state) {
                case TelephonyManager.CALL_STATE_IDLE:
                    //手机空闲了
//                    Log.v("PhoneStateReceiver", "手机空闲了" + incomingNumber);
                    if (Constant.isHujiao && !Constant.isGuaduan) {
                        Log.e(TAG, "等待拨号,然后通话");
                        Constant.isHujiao = false;
                        Constant.isZhujiaoTonghua = true;
                    } else if (Constant.isZhujiaoTonghua && !Constant.isGuaduan) {
                        Log.e(TAG, "呼叫:挂断电话");
                        Constant.guaduanTime = System.currentTimeMillis();
                        bcb.stopRecord();
                        Constant.isZhujiaoTonghua = false;
                        Constant.isGuaduan = true;
                        Constant.number = "";
                    } else if (Constant.isLaiDian && !Constant.isGuaduan && Constant.isLaidianZhaiji) {
                        Log.e(TAG, "接听电话,然后通话");
                        Constant.isLaidianTonghua = true;
                        Constant.isLaiDian = false;
                        Constant.isLaidianZhaiji = false;
                    } else if (Constant.isLaidianTonghua && !Constant.isGuaduan) {
                        Log.e(TAG, "被叫:挂断电话");
                        Constant.guaduanTime = System.currentTimeMillis();
                        bcb.stopRecord();
                        Constant.isLaidianTonghua = false;
                        Constant.isGuaduan = true;
                        Constant.number = "";
                    }
                    break;
                case TelephonyManager.CALL_STATE_OFFHOOK:
                    //电话被挂起
                    Log.d("PhoneStateReceiver", "电话被挂起" + incomingNumber);
                    if (Constant.isZhujiaoZhaiji) {
                        Log.e(TAG, "主叫:摘机状态");
                        Constant.isZhujiaoZhaiji = false;
                        bcb.startRecord();
                    }
                    if (Constant.isLaiDian && !Constant.isLaidianZhaiji) {
                        Log.e(TAG, "被叫:摘机状态");
                        Constant.isLaidianZhaiji = true;
                        bcb.startRecord();
                    }

//                    bcb.startRecord();
                    break;
                case TelephonyManager.CALL_STATE_RINGING:
                    // 当电话呼入时
                    Log.e(TAG, "响铃:来电号码" + incomingNumber);
                    if (!Constant.isLaiDian) {
                        Constant.number = incomingNumber;
                        Log.e(TAG, "响铃:来电号码" + incomingNumber);
                        Constant.isLaiDian = true;
                        Constant.isGuaduan = false;
                        Constant.isLaidianZhaiji = false;
                    }

                    if (!phones.contains(incomingNumber)) {
                        Log.e(TAG, "拦截该号码");
                        Constant.guaduanTime = System.currentTimeMillis();
                        Constant.isGuaduan = true;
                        endCall();
                        if (bcb != null) {
                            bcb.callBack(incomingNumber);
                        }
                    } else {
                        Log.e(TAG, "不拦截该号码");
                    }
                    break;
            }
        }
    }

    public BlockCallHelper setBlockCallBack(BlockCallBack back) {
        this.bcb = back;
        return this;
    }

    public interface BlockCallBack {
        void callBack(String incomingNum);

        void startRecord();

        void stopRecord();
    }
}
